home comics writing pictures archive about

MBRDemo.asm

Language: Assembly
Last Modified: 2025-12-08 2:15:41 AM UTC
File Size: 8011 bytes
http://www.penguinstew.ca/example/MBRDemo/MBRDemo.asm
NAME MBR Demo
TITLE 'MBRDemo.COM --- Demo of MBR Bootstrap program'
cseg SEGMENT PARA PUBLIC 'CODE'
; COM programs start at 100H and only have one segment
ORG 100H
ASSUME CS:cseg,DS:cseg,ES:cseg,SS:cseg
main PROC NEAR
MOV AX, CS ; Store segment in AX so bootstrap code can use it
JMP bootstrap
finish:
MOV AX,4C00H ; Terminate with return code 0
INT 21H
; Used for offsets into the bootstrap copy
ORG 0600H
bootCopy:
ORG 061DH
bootCopyResume:
ORG 068BH
invParMsgCpy:
ORG 06A3H
errLoadMsgCpy:
ORG 06C2H
missOsMsgCpy:
ORG 07BEH
parEntCpy:
ORG 7C00H
bootstrap:
CLI ; Disable interupts
;XOR AX, AX ; In original, set AX = 0
NOP ; Skipped as the demo code
NOP ; set AX = segment already
MOV SS, AX ; Initalize Stack
MOV SP, offset bootstrap
MOV SI, SP
PUSH AX ; Initalize data segments
POP ES
PUSH AX
POP DS
STI ; Enable interupts
CLD ; Clear direction flag
; String operations increment index registers
MOV DI, offset bootCopy ; Set address of copy
MOV CX, 0100H ; Number of words to copy
; 256 words, 512 bytes
;REPNE MOVSW ; Original code uses REPNE
; But this is technically not supported
; because MOVSW doesn't update Z flag
REP MOVSW ; Repeatedly copy words
;JMP 0000061DH ; In original Absoloute JMP
MOV AX, offset bootCopyResume
; In demo use AX to force
; absoloute near jump
JMP AX ; Jmp to copy
MOV SI, offset parEntCpy ; Set address of first partition entry
MOV BL, 04H ; Number of entries
checkPartition:
CMP byte ptr [SI], 80H ; Check if partition is active
JE partitionActive
CMP byte ptr [SI], 00H ; Check if correctly marked inactive
JNE partitionInvalid ; Display invalid partition message if not
ADD SI, 10H ; Move to next partition entry
DEC BL ; Decrement remaning partition count
JNZ checkPartition ; Repeat if there are entries left
;INT 18H ; The original code tries to Boot BASIC
; if no active partitions are found
JMP partitionInvalid ; Display invalid parttition message for demo
partitionActive:
MOV DX, [SI] ; Store Status + partition start heads
MOV CX, [SI] + 02H ; Store partition start cylinder + sector
MOV BP, SI ; Store partition entry address
checkPartitionValid:
ADD SI, 10H ; Move to next partition entry
DEC BL ; Decrement remaning parition count
JZ loadPartition ; If all partitions valid, load active
CMP byte ptr [SI], 00H
; Check if correctly marked inactive
jE checkPartitionValid ; Check next partition if it is
partitionInvalid:
MOV SI, offset invParMsgCpy ; Load address of invalid partition message
printMessage:
LODSB ; load byte from message
CMP AL, 00H ; Check for null terminator
JE messageEnd ; Jump if message is finished
PUSH SI ; Store SI
MOV BX, 0007H ; Display page 0, white text
MOV AH, 0EH ; Write character to screen
INT 10H
POP SI ; Restore SI
JMP printMessage ; Print next character
messageEnd:
;JMP messageEnd ; In original it Loops forever
JMP bootstrapEnd ; Jmp to end for demo
loadPartition:
MOV DI, 0005H ; Set number of retry attempts
loadPartitionLoop:
MOV BX, 7C00H ; Buffer to load data into
MOV AX, 0201H ; Read from disk, 1 sector
PUSH DI ; Store DI
INT 13H
POP DI ; Restore DI
JNC loadOk ; Jump if carry flag clear (No error)
XOR AX, AX ; Set AX = 0, Reset disk system
INT 13H
DEC DI ; Decrenment DI
JNZ loadPartitionLoop ; If not 0, try again
MOV SI, errLoadMsgCpy ; Otherwise display error loading OS
JMP printMessage
loadOk:
MOV SI, missOsMsgCpy ; Preset SI to missing OS message
MOV DI, offset bootSig ; Load the expected location of the boot signature
CMP word ptr [DI], 0AA55H ; Check if boot signature matches
JNE printMessage ; If not, print message
MOV SI, BP ; Restore partion entry offset to SI
;JMP 00007C00H ; In original JMP to loaded partition boot sector
bootstrapEnd:
MOV AX, finish
JMP AX ; Jmp to program exit for demo
main ENDP
invParMsg db 'Invalid partition table', 00H
errLoadMsg db 'Error loading operating system', 00H
missOsMsg db 'Missing operating system', 00H
ORG 7DBEH
;Entry 1
parStatus1 db 00H ; Partition status 80H = Active, 00H = not
parSrtHead1 db 00H ; Head portion of CHS start address
parSrtCySct1 db 00H ; High part of cylinder and sector
parSrtCyLo1 db 00H ; Low part of cylinder
parType1 db 00H ; Partition type
parEndHead1 db 00H ; Head portion of CHS end address
parEndCySct1 db 00H ; High part of cylinder and secto
parEndCyLo1 db 00H ; Low part of cylinder
parSrtLba1 dd 00000000H ; Logical block address start
parLength1 dd 00000000H ; Number of sectors
;Entry 2
parStatus2 db 00H ; Partition status 80H = Active, 00H = not
parSrtHead2 db 00H ; Head portion of CHS start address
parSrtCySct2 db 00H ; High part of cylinder and sector
parSrtCyLo2 db 00H ; Low part of cylinder
parType2 db 00H ; Partition type
parEndHead2 db 00H ; Head portion of CHS end address
parEndCySct2 db 00H ; High part of cylinder and secto
parEndCyLo2 db 00H ; Low part of cylinder
parSrtLba2 dd 00000000H ; Logical block address start
parLength2 dd 00000000H ; Number of sectors
;Entry 3
parStatus3 db 00H ; Partition status 80H = Active, 00H = not
parSrtHead3 db 00H ; Head portion of CHS start address
parSrtCySct3 db 00H ; High part of cylinder and sector
parSrtCyLo3 db 00H ; Low part of cylinder
parType3 db 00H ; Partition type
parEndHead3 db 00H ; Head portion of CHS end address
parEndCySct3 db 00H ; High part of cylinder and secto
parEndCyLo3 db 00H ; Low part of cylinder
parSrtLba3 dd 00000000H ; Logical block address start
parLength3 dd 00000000H ; Number of sectors
;Entry 4
parStatus4 db 00H ; Partition status 80H = Active, 00H = not
parSrtHead4 db 00H ; Head portion of CHS start address
parSrtCySct4 db 00H ; High part of cylinder and sector
parSrtCyLo4 db 00H ; Low part of cylinder
parType4 db 00H ; Partition type
parEndHead4 db 00H ; Head portion of CHS end address
parEndCySct4 db 00H ; High part of cylinder and secto
parEndCyLo4 db 00H ; Low part of cylinder
parSrtLba4 dd 00000000H ; Logical block address start
parLength4 dd 00000000H ; Number of sectors
bootSig dw 0AA55H ; Boot signature
CSEG ENDS
END main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179